package com.lance.core.verticle;



import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.lance.core.base.BC;
import com.lance.core.base.ModelAndView;
import com.lance.core.util.ClassUtil;
import com.lance.core.util.JacksonUtil;
import com.lance.modules.front.login.entity.UserEntity;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.bridge.PermittedOptions;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.ext.web.handler.sockjs.BridgeOptions;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;
import io.vertx.ext.web.templ.HandlebarsTemplateEngine;

public class RootVerticle extends AbstractVerticle {
	
	// In order to use a template we first need to create an engine
    public final HandlebarsTemplateEngine templateEngine = HandlebarsTemplateEngine.create();
//	public static  final FreeMarkerTemplateEngine templateEngine = FreeMarkerTemplateEngine.create();
	public static final Logger log = LogManager.getLogger(RootVerticle.class);
	public void start(Future<Void> future){	
		try {
			final HttpServer server = vertx.createHttpServer();
			Router router = Router.router(vertx);
			
			//resful路由
			for (final Object resfulUrl : BC.SERVICECLASSS.keySet().toArray()) {
				//消息时间机制
				router.routeWithRegex("/"+resfulUrl+"/*.*").handler(this::evHandler);
			}
			
			//静态文件
			router.route("/templates/*").handler(StaticHandler.create().setWebRoot("templates"));
			
			//聊天sockjs
			SockJSHandler sockJSHandler = SockJSHandler.create(vertx);
			BridgeOptions options = new BridgeOptions();
			options.addInboundPermitted(new PermittedOptions().setAddress("chat.to.server"));
			options.addOutboundPermitted(new PermittedOptions().setAddressRegex("server.to.chat*.*"));
			sockJSHandler.bridge(options);
			
			router.route("/socket/*").handler(sockJSHandler);
			
			router.routeWithRegex("/park/*.*").handler(this::parkHandler);
			
//			router.routeWithRegex("/"+BC.EV_WEB+"/*.*").handler(this::indexHandler);
			
			server.requestHandler(router::accept);
			server.listen(config().getInteger("http.port", 8081),result -> {
				if(result.succeeded()){
					future.complete();
				}else{
					future.fail(result.cause());
				}
			});
			
			//初始化公共数据
			vertx.sharedData().<String,UserEntity> getClusterWideMap("USER_TOKEN", res->{
				if(res.succeeded()){
					BC.TOKENMAPPER = res.result();
				}
			});
			
			log.info("httpserver listenning on port : "+config().getInteger("http.port",8081));
		} catch (Exception e) {
			log.error("服务启动异常",e);
		}
		
	}
	
	public void evHandler(RoutingContext routingContext){
		HttpServerResponse response = routingContext.response();
		HttpServerRequest request = routingContext.request();
		String acrm = request.headers().get("Access-Control-Request-Method");
		response.putHeader("Access-Control-Allow-Origin", "*");
		response.putHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
		response.putHeader("Access-Control-Allow-Headers",
				"X-Requested-With, Content-Type, X-Codingpedia,Authentication");
		response.putHeader("content-type", "application/json;charset=utf-8");
		if (acrm != null) {
		    routingContext.response().setStatusCode(200).end();
		    return;
		}
		
		request.bodyHandler(body -> {
			 byte[] bd = body.getBytes();
			 String auth = request.getHeader("Authentication");
			 System.out.println(request.path());
			 if("/userResful/login".equals(ClassUtil.getPath(request.path()))||ClassUtil.getPath(request.path()).startsWith("/pubResful/")){//登录操作,直接放行
				//使用eventbus发送消息
				 EventBus eb = vertx.eventBus();
				 eb.send(ClassUtil.getPath(request.path()), new String(bd),message->{
					 if(message.succeeded()){
						 response.end( message.result().body().toString());
					 }else{
						 routingContext.next();
					 }
				 });
			 }else{
				 
				 BC.TOKENMAPPER.get(auth, res->{
					 if(res.succeeded()&&res.result()!=null){//token校验成功
						 //使用eventbus发送消息
						 EventBus eb = vertx.eventBus();
						 eb.send(ClassUtil.getPath(request.path()), new String(bd),message->{
							 if(message.succeeded()){
								 response.end( message.result().body().toString());
							 }else{
								 routingContext.next();
							 }
						 });
					 }else{// token校验失败
						 response.setStatusCode(401).end("登录超时,请重新登录!");
					 }
				 });
			 }
			 
		});
		

}
	
	public void parkHandler(RoutingContext routingContext){
		HttpServerResponse response = routingContext.response();
		HttpServerRequest request = routingContext.request();
		String acrm = request.headers().get("Access-Control-Request-Method");
		response.putHeader("Access-Control-Allow-Origin", "*");
		response.putHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
		response.putHeader("Access-Control-Allow-Headers",
				"X-Requested-With, Content-Type, X-Codingpedia,Authentication");
		response.putHeader("content-type", "application/json");
		if (acrm != null) {
		    routingContext.response().setStatusCode(200).end();
		    return;
		}
		response.end(request.getParam("a").toString());
		request.bodyHandler(body -> {
			 byte[] bd = body.getBytes();
			 
		});

	}
	
	public void evNoHandler(RoutingContext routingContext){
			HttpServerResponse response = routingContext.response();
			response.putHeader("Access-Control-Allow-Origin", "*");
			response.putHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
			response.putHeader("Access-Control-Allow-Headers",
					"X-Requested-With, Content-Type, X-Codingpedia,Authentication");
			response.putHeader("content-type", "application/json");
			response.setStatusCode(200).end("No resource");
	
	}
	
//	private void indexHandler(RoutingContext context) {
//		HttpServerRequest request = context.request();
//		//使用eventbus发送消息
//		EventBus eb = vertx.eventBus();
//		eb.send(ClassUtil.getPath(request.path()), "datareport",message->{
//			if(message.succeeded()){
//					ModelAndView mav =  (ModelAndView) JacksonUtil.strToObject(message.result().body().toString(),ModelAndView.class);
//					context.put("dt", mav.getData());
//					
//					templateEngine.render(context, "templates", "/header", headerAr -> {
//						if (headerAr.succeeded()) {
//							templateEngine.render(context, "templates", "/footer", footerAr -> {
//								if (footerAr.succeeded()) {
//										templateEngine.render(context, "templates", mav.getPageName(), ar -> {
//											if (ar.succeeded()) {
//												context.response().putHeader("Content-Type", "text/html");
//												Buffer headerBuf = headerAr.result();
//												Buffer contentBuf = ar.result();
//												headerBuf.appendBuffer(contentBuf);
//												Buffer footerBuf = footerAr.result();
//												headerBuf.appendBuffer(footerBuf);
//												context.response().end(headerBuf);
//											} else {
//												context.fail(ar.cause());
//											}
//										});
//								} else {
//									context.fail(footerAr.cause());
//								}
//							});
//						} else {
//							context.fail(headerAr.cause());
//						}
//					});
//			}else{
//				context.next();
//			}
//		});
//		
//		
//	}
}
